/**
  ******************************************************************************
  * @file    modbus_slave.h
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   modbus从机程序(RTU ASCII)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __MODBUS_SLAVE_H
#define __MODBUS_SLAVE_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "modbus_common.h"

/**
 * @addtogroup modbus
 * @{
 */

/**
 * @addtogroup modbus_slave
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup modbus_slave_global_macros modbus slave global macros
 * @{
 */

#define _MBS_DEBUG                      (0u) /*!< modbus从机调试信息打印开关 0:关闭 1:开启 */

#define MBS_NUM                         (3u) /*!< modbus从机管理数量 用户按需修改 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup modbus_slave_global_types modbus slave global types
 * @{
 */

/** 
  * @brief  modbus从机 structure definition
  */
typedef struct mb_slave {
    uint8_t *dataBuf;        /*!< 数据缓存区 */
    uint16_t dataBufLen;     /*!< 数据缓存区长度 */
    volatile uint16_t dataLen;        /*!< 数据长度 */
    volatile uint16_t readLen;        /*!< 读出数据长度 */
    
    uint8_t slaveAddr;       /*!< 从机地址 1~247 */
    uint8_t protocol : 1;    /*!< 协议类型 @ref modbus_common_protocol */
    uint8_t state : 2;       /*!< 请求状态 @ref modbus_common_state */
    
    uint8_t targetFrameIntv; /*!< 目标帧间隔ms */
    uint32_t curFrameIntv;   /*!< 当前帧间隔ms */

    modbus_tx_en_t txEnFn;   /*!< 从机发送前(串口)准备函数 */
} mb_slave_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup modbus_slave_global_functions
 * @{
 */

void mb_slave_init(uint8_t ch, uint8_t slaveAddr, uint8_t protocol, void *pBuf, uint16_t bufLen, modbus_tx_en_t txEnFn, uint32_t baud);

uint8_t mb_slave_poll(uint8_t ch);

uint16_t mb_slave_write_rx_buf(uint8_t ch, void *pBuf, uint16_t len);
uint16_t mb_slave_read_tx_buf(uint8_t ch, void *pBuf, uint16_t len);

/* set/get interface */
void mb_slave_set_slave_addr(uint8_t ch, uint8_t slaveAddr);
uint8_t mb_slave_get_slave_addr(uint8_t ch);
void mb_slave_set_protocol(uint8_t ch, uint8_t protocol);
uint8_t mb_slave_get_protocol(uint8_t ch);
void mb_slave_set_frame_intv(uint8_t ch, uint32_t baud);
uint16_t mb_slave_get_frame_intv(uint8_t ch);

/* 弱定义函数 */
uint8_t mb_slave_req_01h(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);
uint8_t mb_slave_req_02h(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);
uint8_t mb_slave_req_03h(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);
uint8_t mb_slave_req_04h(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);
uint8_t mb_slave_req_05h(uint8_t ch, uint16_t reg, uint8_t bit);
uint8_t mb_slave_req_06h(uint8_t ch, uint16_t reg, uint16_t data);
uint8_t mb_slave_req_0fh(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);
uint8_t mb_slave_req_10h(uint8_t ch, uint16_t reg, uint16_t num, uint8_t *pData);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* modbus_slave.h */
